package com.yunquan.ohana.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.graphics.drawable.shapes.RoundRectShape
import android.text.InputFilter
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.content.ContextCompat
import com.yunquan.ohana.R
import com.yunquan.ohana.utils.Utils

class CodeInputView(
    private val context: Context,
    attrs: AttributeSet?,
    defStyleAttr: Int
) : AppCompatEditText(context, attrs, defStyleAttr) {

    private var mMaxLen = 4
    private var mBorderWidth = 100
    private var mBorderHeight = 100
    private var mBorderRadius = 16
    private var mBorderSpacing = 24
    private var mBorderImage: Drawable? = null

    private val mRect = Rect()

    private var mTextColor: Int? = null

    constructor(context: Context) : this(context, null, 0)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    init {
        if (null == mBorderImage) {
            mBorderImage = ContextCompat.getDrawable(context, R.drawable.bg_code_input_border)
        }
        attrs?.let {
            val typedArray = context.obtainStyledAttributes(it, R.styleable.CodeInputView)
            mMaxLen = typedArray.getInt(R.styleable.CodeInputView_maxLen, 4)
            mBorderWidth = typedArray.getDimensionPixelSize(R.styleable.CodeInputView_borderWidth, -1)
            mBorderHeight = typedArray.getDimensionPixelSize(R.styleable.CodeInputView_borderHeight, -1)
            mBorderRadius = typedArray.getDimensionPixelSize(R.styleable.CodeInputView_borderRadius, 16)
            mBorderSpacing = typedArray.getDimensionPixelSize(R.styleable.CodeInputView_borderSpacing, 24)
            val drawable = typedArray.getDrawable(R.styleable.CodeInputView_borderImage)
            if (null != drawable) {
                mBorderImage = drawable
            }
            if (mBorderWidth == -1) {
                val temp = (Utils.instance.getScreenWidth() - Utils.instance.dp2px(40f) - ((mMaxLen - 1) * mBorderSpacing)) / mMaxLen
                mBorderWidth = temp
                mBorderHeight = mBorderWidth
            }
            typedArray.recycle()
        }
        filters = if (mMaxLen >= 0) {
            arrayOf(InputFilter.LengthFilter(mMaxLen))
        } else {
            arrayOf()
        }
        isLongClickable = false
        isCursorVisible = false
        setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var width = measuredWidth
        var height = mBorderHeight
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        height = if (height < mBorderHeight) mBorderHeight else height
        val len = if (mMaxLen - 1 > 0) mMaxLen - 1 else 0
        val customWidth = mBorderWidth * mMaxLen + mBorderSpacing * (len)
        width = if (width < customWidth) customWidth else width
        val widthSpec = MeasureSpec.makeMeasureSpec(width, widthMode)
        val heightSpec = MeasureSpec.makeMeasureSpec(height, heightMode)
        setMeasuredDimension(widthSpec, heightSpec)
    }

    override fun onDraw(canvas: Canvas) {
        mTextColor = currentTextColor
        setTextColor(Color.TRANSPARENT)
        super.onDraw(canvas)
        setTextColor(mTextColor!!)
        drawBorderBackground(canvas)
        drawText(canvas)
    }

    private fun drawBorderBackground(canvas: Canvas) {
        mRect.left = 0
        mRect.top = 0
        mRect.right = mBorderWidth
        mRect.bottom = mBorderHeight
        val count = canvas.saveCount
        canvas.save()
        val len = editableText.length
        for (i in 0 until mMaxLen) {
            mBorderImage?.bounds = mRect
            mBorderImage?.state = if (i == len) {
                arrayOf(android.R.attr.state_focused).toIntArray()
            } else {
                arrayOf(android.R.attr.state_enabled).toIntArray()
            }
            mBorderImage?.draw(canvas)
            val dx = mRect.right + mBorderSpacing
            canvas.save()
            canvas.translate(dx.toFloat(), 0f)
        }
        canvas.restoreToCount(count)
        canvas.translate(0f, 0f)
    }

    private fun drawText(canvas: Canvas) {
        val count = canvas.saveCount
        canvas.translate(0f, 0f)
        val len = editableText.length
        for (i in 0 until len) {
            val text = editableText[i].toString()
            paint.color = mTextColor!!
            paint.getTextBounds(text, 0, 1, mRect)
            val x = mBorderWidth / 2 + (mBorderWidth + mBorderSpacing) * i - mRect.centerX()
            val y = canvas.height / 2 + mRect.height() / 2
            canvas.drawText(text, x.toFloat(), y.toFloat(), paint)
        }
        canvas.restoreToCount(count)
    }
}